<!DOCTYPE html>
<html lang="en"><head>
    <title>CZH-DEV BLOG</title>
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="format-detection" content="telephone=no" />
    <meta name="theme-color" content="#000084" />
    <link rel="icon" href="https://czh-dev.gitee.io/czh-blog.gitee.io//favicon.ico">
    <link rel="canonical" href="https://czh-dev.gitee.io/czh-blog.gitee.io/">
    
    
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="navbar-inner">
        <div class="container">
            <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"></button>
            <a class="brand" href="https://czh-dev.gitee.io/czh-blog.gitee.io/">CZH-DEV BLOG</a>
            <div class="nav-collapse collapse">
                <ul class="nav">
                    
                    
                        
                            <li>
                                <a href="/czh-blog.gitee.io/about/">
                                    
                                    <span>About</span>
                                </a>
                            </li>
                        
                    
                        
                            <li>
                                <a href="/czh-blog.gitee.io/post/">
                                    
                                    <span>All posts</span>
                                </a>
                            </li>
                        
                    
                        
                            <li>
                                <a href="/czh-blog.gitee.io/ebook/">
                                    
                                    <span>Resource</span>
                                </a>
                            </li>
                        
                    
                </ul>
            </div>
        </div>
    </div>
</nav><div id="content" class="container">
<div style="display: flex;">
  <div class="row-fluid navmargin">
    <div class="page-header">
      <h1>SpringBoot图片上传 - Sat, Feb 11, 2023</h1>
    </div>
    <p class="lead"></p>
    <h1 id="springboot项目图片上传">SpringBoot项目图片上传</h1>
<h2 id="保存到本地">保存到本地</h2>
<blockquote>
<p><strong>可参考视频：</strong></p>
<p>【springboot上传图片的两种方式详解（本地/OSS对象存储）】 <a href="https://www.bilibili.com/video/BV1TK411Z7ad/?share_source=copy_web&amp;vd_source=7f0416c71bcbaf44e08ad58367e3f198">https://www.bilibili.com/video/BV1TK411Z7ad/?share_source=copy_web&amp;vd_source=7f0416c71bcbaf44e08ad58367e3f198</a></p>
<p>视频前十分钟是从0开始编写图片保存到本地，可以照着视频敲出来，不想看也可以直接复制我下面的代码</p>
</blockquote>
<ul>
<li>
<p>在<code>Resources</code>目录下有一个<code>upload.html</code>文件，和一个<code>static</code>文件夹，<code>static</code>下又有一个<code>images</code>文件夹，如下图</p>
<p><img src="https://img-blog.csdnimg.cn/d95ddd169dbd4c37b0e64ec7d0da2555.png#pic_center" alt="在这里插入图片描述"></p>
</li>
</ul>
<h3 id="uploadhtml">upload.html</h3>
<ul>
<li>
<p>upload.html</p>
<p>这里主要就是一个form表单，用来提交数据，但是要注意的是我这个表单用了<code>post</code>和<code>enctype=&quot;multipart/form-data&quot;</code>，以及input的类型是<code>file</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span><span style="color:#75715e">&lt;!DOCTYPE html&gt;</span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">html</span> <span style="color:#a6e22e">lang</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;en&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">head</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">meta</span> <span style="color:#a6e22e">charset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;UTF-8&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">title</span>&gt;上传图片&lt;/<span style="color:#f92672">title</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">head</span>&gt;
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">body</span>&gt;
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">form</span> <span style="color:#a6e22e">action</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/uplaod&#34;</span> <span style="color:#a6e22e">method</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;post&#34;</span> <span style="color:#a6e22e">enctype</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;multipart/form-data&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;file&#34;</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;file&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;请选择你要上传的图片&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;submit&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;上传&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">form</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">body</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">html</span>&gt;
</span></span></code></pre></div></li>
</ul>
<h3 id="controller">controller</h3>
<ul>
<li>
<p>UploadController</p>
<p><strong>想直接看源码的同学可以跳过分析，往下滑</strong></p>
<p>为了方便演示，我把业务都放在controller，，首先我们要先分析文件上传有几步</p>
<ol>
<li>
<p>文件校验（包括但不限于，图片的大小、图片的类型、图片是否为空、上传的是否是文件等）</p>
<ul>
<li>我这里只做了一个判空的校验，可以自己加需要的校验</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>file<span style="color:#f92672">.</span><span style="color:#a6e22e">isEmpty</span><span style="color:#f92672">())</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;图片上传失败&#34;</span><span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div></li>
<li>
<p>将图片重命名，图片重命名又可分为以下几步</p>
<ul>
<li>
<p>获取原来文件的后缀名，可以使用<code>file.getOriginalFilename()</code>获取原来的文件名</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span>String originalFilename <span style="color:#f92672">=</span> file<span style="color:#f92672">.</span><span style="color:#a6e22e">getOriginalFilename</span><span style="color:#f92672">();</span> <span style="color:#75715e">//原来的图片名
</span></span></span></code></pre></div></li>
<li>
<p>生成一个随机的新文件名，这里可以使用<code>UUID.randomUUID()</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span>String uuid <span style="color:#f92672">=</span> UUID<span style="color:#f92672">.</span><span style="color:#a6e22e">randomUUID</span><span style="color:#f92672">().</span><span style="color:#a6e22e">toString</span><span style="color:#f92672">().</span><span style="color:#a6e22e">replace</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;-&#34;</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;&#34;</span><span style="color:#f92672">);</span>
</span></span></code></pre></div></li>
<li>
<p>把新名称和原后缀名拼接起来作为新的文件名</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span>String fileName <span style="color:#f92672">=</span> uuid <span style="color:#f92672">+</span> ext<span style="color:#f92672">;</span>
</span></span></code></pre></div></li>
</ul>
</li>
<li>
<p>把图片上传的指定的目录下，我们这里讲的是<code>Resources</code>，就以<code>Resources</code>为例</p>
<ul>
<li>
<p><code>new ApplicationHome(this.getClass())</code>可以获取当前程序运行的路径</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span>ApplicationHome applicationHome <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> ApplicationHome<span style="color:#f92672">(</span><span style="color:#66d9ef">this</span><span style="color:#f92672">.</span><span style="color:#a6e22e">getClass</span><span style="color:#f92672">());</span>
</span></span></code></pre></div></li>
<li>
<p>我们知道Java程序都是运行的.class字节码文件，所以<code>getDir()</code>获取文件夹位置其实是.class字节码文件的位置，需要使用<code>getParentFile()</code>两次回到项目的主程序目录</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span>applicationHome<span style="color:#f92672">.</span><span style="color:#a6e22e">getDir</span><span style="color:#f92672">().</span><span style="color:#a6e22e">getParentFile</span><span style="color:#f92672">().</span><span style="color:#a6e22e">getParentFile</span><span style="color:#f92672">().</span><span style="color:#a6e22e">getAbsolutePath</span><span style="color:#f92672">()</span>
</span></span></code></pre></div></li>
<li>
<p>获取到主目录的绝对路径拼接上从这里到<code>Resources</code>下的<code>images</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span>String pre <span style="color:#f92672">=</span> applicationHome<span style="color:#f92672">.</span><span style="color:#a6e22e">getDir</span><span style="color:#f92672">().</span><span style="color:#a6e22e">getParentFile</span><span style="color:#f92672">().</span><span style="color:#a6e22e">getParentFile</span><span style="color:#f92672">().</span><span style="color:#a6e22e">getAbsolutePath</span><span style="color:#f92672">()</span> <span style="color:#f92672">+</span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;\\src\\main\\resources\\static\\images\\&#34;</span><span style="color:#f92672">;</span>
</span></span></code></pre></div></li>
<li>
<p>最后通过<code>file.transferTo(new File(path));</code>把文件上传到<code>Resources</code>下的<code>images</code>目录，并且返回一个url地址</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span>String path <span style="color:#f92672">=</span> pre <span style="color:#f92672">+</span> fileName<span style="color:#f92672">;</span>
</span></span></code></pre></div></li>
</ul>
</li>
</ol>
<p><strong>完整controller代码：</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#a6e22e">@RestController</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">UploadController</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@PostMapping</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;/uplaod&#34;</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> String <span style="color:#a6e22e">upload</span><span style="color:#f92672">(</span>MultipartFile file<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">//图片校验（图片是否为空,图片大小，上传的是不是图片、图片类型（例如只能上传png）等等）
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>file<span style="color:#f92672">.</span><span style="color:#a6e22e">isEmpty</span><span style="color:#f92672">())</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;图片上传失败&#34;</span><span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">//可以自己加一点校验 例如上传的是不是图片或者上传的文件是不是png格式等等 这里省略
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#75715e">//获取原来的文件名和后缀
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        String originalFilename <span style="color:#f92672">=</span> file<span style="color:#f92672">.</span><span style="color:#a6e22e">getOriginalFilename</span><span style="color:#f92672">();</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">//        String ext = &#34;.&#34; + FilenameUtils.getExtension(orgFileName); --需要导依赖
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        String ext <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;.&#34;</span><span style="color:#f92672">+</span> originalFilename<span style="color:#f92672">.</span><span style="color:#a6e22e">split</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;\\.&#34;</span><span style="color:#f92672">)[</span>1<span style="color:#f92672">];</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">//生成一个新的文件名（以防有重复的名字存在导致被覆盖）
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        String uuid <span style="color:#f92672">=</span> UUID<span style="color:#f92672">.</span><span style="color:#a6e22e">randomUUID</span><span style="color:#f92672">().</span><span style="color:#a6e22e">toString</span><span style="color:#f92672">().</span><span style="color:#a6e22e">replace</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;-&#34;</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;&#34;</span><span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span>        String newName <span style="color:#f92672">=</span> uuid <span style="color:#f92672">+</span> ext<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">//拼接图片上传的路径 url+图片名
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        ApplicationHome applicationHome <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> ApplicationHome<span style="color:#f92672">(</span><span style="color:#66d9ef">this</span><span style="color:#f92672">.</span><span style="color:#a6e22e">getClass</span><span style="color:#f92672">());</span>
</span></span><span style="display:flex;"><span>        String pre <span style="color:#f92672">=</span> applicationHome<span style="color:#f92672">.</span><span style="color:#a6e22e">getDir</span><span style="color:#f92672">().</span><span style="color:#a6e22e">getParentFile</span><span style="color:#f92672">().</span><span style="color:#a6e22e">getParentFile</span><span style="color:#f92672">().</span><span style="color:#a6e22e">getAbsolutePath</span><span style="color:#f92672">()</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;\\src\\main\\resources\\static\\images\\&#34;</span><span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>        String path <span style="color:#f92672">=</span> pre <span style="color:#f92672">+</span> newName<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">try</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>            file<span style="color:#f92672">.</span><span style="color:#a6e22e">transferTo</span><span style="color:#f92672">(</span><span style="color:#66d9ef">new</span> File<span style="color:#f92672">(</span>path<span style="color:#f92672">));</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">}</span> <span style="color:#66d9ef">catch</span> <span style="color:#f92672">(</span>IOException e<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>            e<span style="color:#f92672">.</span><span style="color:#a6e22e">printStackTrace</span><span style="color:#f92672">();</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> path<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div></li>
</ul>
<blockquote>
<p><code>**注意：**</code></p>
<p>这里截取后缀名我为了代码简洁，直接链式调用获取<code>[1]</code>索引位置的后缀，但是这样不太好，可以获取分割出来的字符串数组的最后一个元素</p>
</blockquote>
<h3 id="运行">运行</h3>
<ul>
<li>
<p>启动Spring Boot项目</p>
</li>
<li>
<p>访问 http://localhost:8080/upload.html 路径，在浏览器打开<code>upload.html</code></p>
<p><img src="https://img-blog.csdnimg.cn/91717b859945448f8e8a230d8da4d3bb.png#pic_center" alt="在这里插入图片描述"></p>
</li>
<li>
<p>选择上传的图片，点击上传</p>
</li>
<li>
<p>上传成功后，浏览器返回保存后的绝对路径（这里我为了容易看懂返回的是<strong>绝对路径</strong>，一般项目中用到的其实是<strong>相对路径</strong>），如果图片上传失败，浏览器会显示<code>图片上传失败</code>的提示信息</p>
<p><img src="https://img-blog.csdnimg.cn/ae66f061d2264b949e824f5362c95d1f.png#pic_center" alt="在这里插入图片描述"></p>
</li>
<li>
<p>图片上传完成之后，我们可以到项目中的<code>/images</code>目录下查看，如果图片存在就说明我们已经成功的将图片上传到我们的项目中了</p>
<p><img src="https://img-blog.csdnimg.cn/6e63e273caf4418eab7058ed71d73243.png#pic_center" alt="在这里插入图片描述"></p>
</li>
<li>
<p>同样，我们可以到浏览器访问这张图片</p>
<p><img src="https://img-blog.csdnimg.cn/a202d292c52448dcb2e92e1371864f37.png#pic_center" alt="在这里插入图片描述"></p>
</li>
<li>
<p>一般项目中其实并不会到这一步就结束，而是将这个图片的路径保存到数据库，但是我这里就不继续往下演示了</p>
</li>
</ul>
<p>将图片上传到本地的功能也实现了，有需要的同学可以继续往下看OSS对象存储</p>
<h2 id="oss对象存储">OSS对象存储</h2>
<p><img src="https://img-blog.csdnimg.cn/484cc9298456492f8cd31ab72dcebc30.png#pic_center" alt="在这里插入图片描述"></p>
<p>在分布式项目中，通常一个项目中会用到很多服务器，如果我们还像单体项目中将文件/图片上传到本地，而下一次访问的时候，如果我们访问的服务器不是上一次保存的服务器的话，我们就访问不到自己上传的数据，这显然不是我们希望的，这时候我们就用到OSS对象存储</p>
<ol>
<li>
<p>首先你需要一个阿里云OSS对象存储</p>
<p>创建Bucket</p>
<ul>
<li>名称：随便起</li>
<li>地域：想你的服务器在哪就选哪个（也是随便选）</li>
<li>存储类型：标准存储</li>
<li>冗余存储：关闭</li>
<li>版本控制：关闭</li>
<li>读写权限：公共读写</li>
</ul>
<p><img src="https://img-blog.csdnimg.cn/6801dc329542488ea15a5a13679710e8.png#pic_center" alt="在这里插入图片描述"></p>
<blockquote>
<p><strong>具体流程可以参考视频：</strong></p>
<p>【springboot上传图片的两种方式详解（本地/OSS对象存储）】 <a href="https://www.bilibili.com/video/BV1TK411Z7ad/?share_source=copy_web&amp;vd_source=7f0416c71bcbaf44e08ad58367e3f198">https://www.bilibili.com/video/BV1TK411Z7ad/?share_source=copy_web&amp;vd_source=7f0416c71bcbaf44e08ad58367e3f198</a></p>
<p>这个视频从11分钟开始讲的是OSS对象存储，照着视频做一样可以实现，另外本篇博客也是基于该视频</p>
</blockquote>
</li>
<li>
<p>代码</p>
<ul>
<li>
<p>导入依赖</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672">&lt;dependency&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;groupId&gt;</span>com.aliyun.oss<span style="color:#f92672">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;artifactId&gt;</span>aliyun-sdk-oss<span style="color:#f92672">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;version&gt;</span>3.15.0<span style="color:#f92672">&lt;/version&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/dependency&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;dependency&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;groupId&gt;</span>commons-io<span style="color:#f92672">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;artifactId&gt;</span>commons-io<span style="color:#f92672">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;version&gt;</span>2.4<span style="color:#f92672">&lt;/version&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/dependency&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;dependency&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;groupId&gt;</span>commons-beanutils<span style="color:#f92672">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;artifactId&gt;</span>commons-beanutils<span style="color:#f92672">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;version&gt;</span>1.9.3<span style="color:#f92672">&lt;/version&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/dependency&gt;</span>
</span></span></code></pre></div></li>
<li>
<p>新建一个工具类UploadUtil在util包下</p>
<ol>
<li>
<p>需要到阿里云官网获取几个参数</p>
<ul>
<li>
<p>阿里域名（<code>开头加https://，结尾加/</code>，这个不能漏）</p>
</li>
<li>
<p>地域节点（<code>开头加http://</code>，一样不能少）</p>
<p><img src="https://img-blog.csdnimg.cn/5dd3a433e1b14164a1f72a4f18030286.png#pic_center" alt="在这里插入图片描述"></p>
</li>
<li>
<p>accessKeyId</p>
</li>
<li>
<p>accessKeySecret</p>
<p><img src="https://img-blog.csdnimg.cn/61fa88c6e39e4c628e710e6abb0e3388.png#pic_center" alt="在这里插入图片描述"></p>
</li>
</ul>
</li>
<li>
<p>生成一个新的文件名</p>
</li>
<li>
<p>使用OSS客户端对象上传图片返回url</p>
</li>
</ol>
<h4 id="uploadutil">UploadUtil</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">UploadUtil</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">//域名(开头需要https://，结尾要/)
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">final</span> String ALI_DOMAIN <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;https://你的阿里云域名/&#34;</span><span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> String <span style="color:#a6e22e">uploadImg</span><span style="color:#f92672">(</span>MultipartFile file<span style="color:#f92672">)</span> <span style="color:#66d9ef">throws</span> Exception <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">//生成的文件名
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        String uuid <span style="color:#f92672">=</span> UUID<span style="color:#f92672">.</span><span style="color:#a6e22e">randomUUID</span><span style="color:#f92672">().</span><span style="color:#a6e22e">toString</span><span style="color:#f92672">().</span><span style="color:#a6e22e">replace</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;-&#34;</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;&#34;</span><span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span>        String originalFilename <span style="color:#f92672">=</span> file<span style="color:#f92672">.</span><span style="color:#a6e22e">getOriginalFilename</span><span style="color:#f92672">();</span>
</span></span><span style="display:flex;"><span>        String ext <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;.&#34;</span> <span style="color:#f92672">+</span> FilenameUtils<span style="color:#f92672">.</span><span style="color:#a6e22e">getExtension</span><span style="color:#f92672">(</span>originalFilename<span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span>        String fileName <span style="color:#f92672">=</span> uuid <span style="color:#f92672">+</span> ext<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">//地域节点(开头需要http://)
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        String endpoint <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;你的地域节点&#34;</span><span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>        String accessKeyId <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;你的accessKeyId&#34;</span><span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>        String accessKeySecret <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;你的accessKeySecret&#34;</span><span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">//OSS客户端对象
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        OSS ossClient <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> OSSClientBuilder<span style="color:#f92672">().</span><span style="color:#a6e22e">build</span><span style="color:#f92672">(</span>endpoint<span style="color:#f92672">,</span> accessKeyId<span style="color:#f92672">,</span> accessKeySecret<span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span>        ossClient<span style="color:#f92672">.</span><span style="color:#a6e22e">putObject</span><span style="color:#f92672">(</span>
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;你的仓库名&#34;</span><span style="color:#f92672">,</span> <span style="color:#75715e">//仓库名
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>                fileName<span style="color:#f92672">,</span> <span style="color:#75715e">//文件名
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>                file<span style="color:#f92672">.</span><span style="color:#a6e22e">getInputStream</span><span style="color:#f92672">()</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span>        ossClient<span style="color:#f92672">.</span><span style="color:#a6e22e">shutdown</span><span style="color:#f92672">();</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> ALI_DOMAIN <span style="color:#f92672">+</span> fileName<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div><h4 id="controller-1">controller</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#a6e22e">@PostMapping</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;/upImg&#34;</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> String <span style="color:#a6e22e">upImg</span><span style="color:#f92672">(</span>MultipartFile file<span style="color:#f92672">)</span> <span style="color:#66d9ef">throws</span> IOException <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> UploadUtil<span style="color:#f92672">.</span><span style="color:#a6e22e">uploadImage</span><span style="color:#f92672">(</span>file<span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div><h4 id="uploadhtml-1">upload.html</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#f92672">form</span> <span style="color:#a6e22e">action</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/upImg&#34;</span> <span style="color:#a6e22e">method</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;post&#34;</span> <span style="color:#a6e22e">enctype</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;multipart/form-data&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;file&#34;</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;file&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;上传图片&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;submit&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;上传&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">form</span>&gt;
</span></span></code></pre></div></li>
<li>
<p>测试方法和本地运行一致</p>
</li>
<li>
<p>上传成功后可以讲路径复制到浏览器访问，也可以打开阿里云官网OSS对象存储查看上传的图片</p>
</li>
</ul>
<p><img src="https://img-blog.csdnimg.cn/ca98c805611148f6b8b3b73984c26e55.png#pic_center" alt="在这里插入图片描述"></p>
</li>
</ol>
<h2 id="可能会遇到的问题">可能会遇到的问题</h2>
<h3 id="如何搭建spring-boot项目">如何搭建spring boot项目</h3>
<p>搭建一个spring boot项目</p>
<ul>
<li>pom.xml导入web依赖</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672">&lt;dependency&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;groupId&gt;</span>org.springframework.boot<span style="color:#f92672">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;artifactId&gt;</span>spring-boot-starter-web<span style="color:#f92672">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/dependency&gt;</span>
</span></span></code></pre></div><ul>
<li>编写启动类</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#a6e22e">@SpringBootApplication</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Run</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">main</span><span style="color:#f92672">(</span>String<span style="color:#f92672">[]</span> args<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>        SpringApplication<span style="color:#f92672">.</span><span style="color:#a6e22e">run</span><span style="color:#f92672">(</span>Run<span style="color:#f92672">.</span><span style="color:#a6e22e">class</span><span style="color:#f92672">,</span> args<span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div><h3 id="如何使用postman测试文件上传">如何使用Postman测试文件上传</h3>
<p>如果要使用postman测试，可以不用写html页面</p>
<p>Params上加上<code>Content-Type=multipart/form-data</code>，Body中选择<code>form-data</code>
<img src="https://img-blog.csdnimg.cn/3dd7e3ac2ce4425d98a44bc5ba79fde1.png#pic_center" alt="在这里插入图片描述"></p>
<p><img src="https://img-blog.csdnimg.cn/b32c092cf2cd44dcb922afbf82d84bae.png#pic_center" alt="在这里插入图片描述"></p>

    <h4><a href="https://czh-dev.gitee.io/czh-blog.gitee.io/">Back to Home</a></h4>
  </div>

  <div class="span3 bs-docs-sidebar" style="position:fixed;right: 40px;top: 50px;">
    <h1>catalogue</h1>
    <ul class="nav nav-list bs-docs-sidenav">
      <div class="toc-div">
        <nav id="TableOfContents">
  <ul>
    <li><a href="#保存到本地">保存到本地</a>
      <ul>
        <li><a href="#uploadhtml">upload.html</a></li>
        <li><a href="#controller">controller</a></li>
        <li><a href="#运行">运行</a></li>
      </ul>
    </li>
    <li><a href="#oss对象存储">OSS对象存储</a>
      <ul>
        <li></li>
      </ul>
    </li>
    <li><a href="#可能会遇到的问题">可能会遇到的问题</a>
      <ul>
        <li><a href="#如何搭建spring-boot项目">如何搭建spring boot项目</a></li>
        <li><a href="#如何使用postman测试文件上传">如何使用Postman测试文件上传</a></li>
      </ul>
    </li>
  </ul>
</nav>
      </div>
    </ul>
  </div>

</div>
<script src="https://cdn.jsdelivr.net/npm/gumshoejs@5.1.2/dist/gumshoe.min.js"></script>
<script>
  var spy = new Gumshoe('#TableOfContents a', {
    nested: true,
    nestedClass: 'active'
  });
</script>
<style>
   
  #TableOfContents li,
  #TableOfContents ul {
    list-style-type: none;
  }

  #TableOfContents ul {
    padding-left: 0px;
  }

  #TableOfContents li>a {
    display: block;
    padding: 4px 20px;
    font-size: 95%;
    color: #000000;
  }

  #TableOfContents li>a:hover,
  #TableOfContents li>a:focus {
    padding-left: 19px;
    color: #3A6bA5;
    text-decoration: none;
    background-color: transparent;
    border-left: 1px solid #3A6bA5;
  }

  #TableOfContents li.active>a,
  #TableOfContents li.active>a:hover,
  #TableOfContents li.active>a:focus {
    padding-left: 18px;
    font-weight: bold;
    color: #3A6bA5;
    background-color: transparent;
    border-left: 2px solid #3A6bA5;
  }

   
  #TableOfContents li>ul {
    padding-bottom: 10px;
  }

  #TableOfContents li li>a {
    padding-top: 1px;
    padding-bottom: 1px;
    padding-left: 30px;
    font-size: 14px;
    font-weight: normal;
  }

  #TableOfContents li li>a:hover,
  #TableOfContents li li>a:focus {
    padding-left: 29px;
  }

  #TableOfContents li li.active>a,
  #TableOfContents li li.active>a:hover,
  #TableOfContents li li.active>a:focus {
    padding-left: 28px;
    font-weight: 500;
  }

  #TableOfContents .nav-link.active+ul {
    display: block;
  }

  #TableOfContents li>ul {
    display: none;
  }

  #TableOfContents li.active>ul {
    display: inherit;
  }

  .toc-div {
    position: -webkit-sticky;
     
    position: sticky;
     
    top: 20px;
  }
</style>


        </div><footer class="container">
    <hr class="soften">
    <p>
    <a href="https://space.bilibili.com/1799809923">Love eating fried pork ribs</a> | 

&copy; 
<a href="http://jmf-portfolio.netlify.com" target="_blank">
    JM Fergeau
</a>
<span id="thisyear">2023</span>

    | My site


        | Built on <a href="//gohugo.io" target="_blank">Hugo</a>

</p>
    <p class="text-center">
        <a href="https://facebook.com">Facebook</a> 
        <a href="https://twitter.com">Twitter</a> 
        <a href="https://linkedin.com">Linkedin</a> 
        <a href="https://github.com">GitHub</a> 
        <a href="https://gitlab.com">GitLab</a>
    </p>
</footer>

</body><link rel="stylesheet" href="/czh-blog.gitee.io/css/bootstrap.css">
<link rel="stylesheet" href="/czh-blog.gitee.io/css/bootstrap-responsive.css">
<link rel="stylesheet" href="/czh-blog.gitee.io/css/style.css">

<script src="/czh-blog.gitee.io/js/jquery.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-386.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-transition.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-alert.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-modal.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-dropdown.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-scrollspy.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-tab.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-tooltip.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-popover.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-button.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-collapse.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-carousel.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-typeahead.js"></script>
<script src="/czh-blog.gitee.io/js/bootstrap-affix.js"></script>
<script>
    _386 = { 
        fastLoad: false ,
        onePass: false , 
        speedFactor: 1 
    };

    
    function ThisYear() {
        document.getElementById('thisyear').innerHTML = new Date().getFullYear();
    };
</script>
</html>
